package com.yc.spring.aop.proxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyDemo {
    public static void main(String[] args) {
        人 zhangsan=new 被告();
        人 lushi=new 律师();
        ((律师) lushi).person=zhangsan;
        lushi.say();
        System.out.println("================");
        人 wangwu=jdkProxy(zhangsan);
        wangwu.say();
        System.out.println("================");
        律师2 a=new 律师2();
        a.say();
        System.out.println("================");
        人 abc=cglibProxy(zhangsan);
        abc.say();
    }
    //基于接口实现的动态代理，有jdk提供的方法
    public static <T> T jdkProxy(T t){
        return (T) Proxy.newProxyInstance(
                t.getClass().getClassLoader(),
                t.getClass().getInterfaces(),
                (proxy,method,args)->{
                    if(method.getName().equals("say")){
                        System.out.println("被告证词");
                        Object ret=method.invoke(t,args);
                        System.out.println("我有证据");
                        return ret;
                    }
                    return null;
                }
        );
    }
    //基于继承的动态代理，CGLIB(动态字节码) 提供的方法
    public static <T> T cglibProxy(T t){
        Enhancer enhancer=new Enhancer();
        //设置父类
        enhancer.setSuperclass(t.getClass());
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(
                    Object o,
                    Method method,
                    Object[] objects,
                    MethodProxy methodProxy) throws Throwable {
                //o 代理对象 ，method 方法，objects参数，methodProxy 方法代理对象
                if(method.getName().equals("say")){
                    System.out.println("被告证词");
                    Object ret=method.invoke(t,objects);
                    System.out.println("我有证据");
                    return ret;
                }
                return null;
            }
        });
        return (T) enhancer.create();
    }
}
interface 人{
    void say();
}

class 被告 implements 人{

    @Override
    public void say() {
        System.out.println("我没罪");
    }
}
class 律师 implements 人{
    人 person;
    @Override
    public void say() {
        System.out.println("被告供词");
        person.say();
        System.out.println("我有证据");
    }
}
class 律师2 extends 被告{
    public void say(){
        System.out.println("被告供词");
        super.say();
        System.out.println("我有证据");
    }
}
